package com.itxiao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itxiao.constants.Constants;
import com.itxiao.dao.*;
import com.itxiao.entity.Category;
import com.itxiao.entity.Sku;
import com.itxiao.entity.Spu;
import com.itxiao.entity.SpuCategory;
import com.itxiao.exception.BusinessException;
import com.itxiao.pojo.bo.Page;
import com.itxiao.pojo.bo.spu.AddSpuReq;
import com.itxiao.pojo.bo.spu.SkuInfo;
import com.itxiao.pojo.bo.spu.SkuSpace;
import com.itxiao.pojo.bo.spu.SpecInfo;
import com.itxiao.pojo.vo.R;
import com.itxiao.pojo.vo.spu.GetSpuVo;
import com.itxiao.pojo.vo.spu.QuerySpuListWithPlatformVo;
import com.itxiao.pojo.vo.spu.SpuListItem;
import com.itxiao.service.SpuService;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品表(Spu)表服务实现类
 *
 * @author makejava
 * @since 2025-10-12 17:07:26
 */
@Service
public class SpuServiceImpl extends ServiceImpl<SpuDao, Spu> implements SpuService {
    private static final Logger log = LoggerFactory.getLogger(SpuService.class);

    @Resource
    private SpuDao spuDao;
    @Resource
    private SpuCategoryDao spuCategoryDao;
    @Resource
    private CategoryDao categoryDao;
    @Resource
    private SkuDao skuDao;

    @Transactional
    @Override
    public R add(AddSpuReq req) {
        // 1. 校验数据：检查分类是否存在且数量匹配
        try {
            checkSpuData(req.getCategoryPath());

            // 2. 添加 SPUM
            Long spuId = addSpu(req);

            // 3. 添加 SKU
            addSku(req, spuId, req.getTitle());

            // 4. 添加 分类关联
            addOther(req.getCategoryPath(), spuId);
            return R.ok(spuId);
        } catch (Exception e) {
            log.error("添加商品失败", e);
            return R.fail("添加失败");
        }
    }

    @Override
    public R querySpuList(Page req) {
        QuerySpuListWithPlatformVo resp = new QuerySpuListWithPlatformVo();
        try {
            // 查询数据库（模拟 QueryPlatformListByCond）
            List<SpuListItem> spuList = spuDao.queryListByPage(req);
            Long total = spuDao.countByPage(req);

            if (total == 0) {
                resp.setList(new ArrayList<>());
                resp.setTotal(0L);
                return R.ok(resp);
            }
            resp.setList(spuList);
            resp.setTotal(total);
            return R.ok(resp);

        } catch (Exception e) {
            log.error("查询 spu 列表失败", e);
            resp.setList(new ArrayList<>());
            resp.setTotal(0L);
            return R.fail("查询失败");
        }
    }

    @Override
    public R queryDetail(Integer id) {
        // 1. 查询 SPU 信息
        Spu spu = spuDao.selectById(id);
        if (spu == null) {
            return R.fail("查找商品失败：商品不存在");
        }
        // 在 queryDetail 方法内
        List<SkuSpace> skuSpaceObj = null;
        if (spu.getSkuSpaces() != null && !spu.getSkuSpaces().trim().isEmpty()) {
            try {
                skuSpaceObj = JSON.parseObject(spu.getSkuSpaces(), new TypeReference<List<SkuSpace>>() {
                });
            } catch (Exception e) {
                log.warn("解析商品规格信息失败，spuId: {}", id, e);
            }
        }

        // 2. 查询所有关联的 SKU 列表
        List<Sku> skuList = skuDao.selectList(
                new LambdaQueryWrapper<Sku>()
                        .eq(Sku::getSpuId, id));

        if (skuList == null) {
            return R.fail("查找规格失败");
        }
        // 4. 处理图片列表
        List<String> images = new ArrayList<>();
        if (spu.getImages() != null && !spu.getImages().trim().isEmpty()) {
            String[] arr = spu.getImages().split(Constants.IMAGE_SEPARATOR);
            for (String img : arr) {
                if (img != null && !img.trim().isEmpty()) {
                    images.add(img.trim());
                }
            }
        }
        List<Long> categoryIds = new ArrayList<>();
        if (spu.getCategoryPath() != null && !spu.getCategoryPath().trim().isEmpty()) {
            String[] arr = spu.getCategoryPath().split(Constants.CATEGORY_SEPARATOR);
            for (String categoryId : arr) {
                if (categoryId != null && !categoryId.trim().isEmpty()) {
                    categoryIds.add(Long.valueOf(categoryId.trim()));
                }
            }
        }

        // 5. 构建返回 VO
        GetSpuVo spuInfo = GetSpuVo.builder()
                .id(spu.getId())
                .title(spu.getTitle())
                .desc(spu.getDescription())
                .itemCode(spu.getItemCode())
                .thumbnail(spu.getThumbnail())
                .skuSpace(skuSpaceObj)
                .categoryPath(categoryIds)
                .salePrice(intToDecimal(spu.getSalePrice()))
                .suggestPrice(intToDecimal(spu.getSuggestPrice()))
                .costPrice(intToDecimal(spu.getCostPrice()))
                .stock(spu.getStock() != null ? spu.getStock() : 0)
                .video(spu.getVideo())
                .images(images)
                .saleType(spu.getSaleType())
                .expressTemplateId(spu.getExpressTemplateId())
                .expressFee(intToDecimal(spu.getExpressFee()))
                .shopId(spu.getShopId())
                .sort(spu.getSort())
                .build();
        //获取skuId的
        List<Long> skuIds = new ArrayList<>();
        List<SkuInfo> skuInfoList = new ArrayList<>();
        for (Sku sku : skuList) {
            skuIds.add(sku.getId());
            SkuInfo skuInfo = new SkuInfo();
            BeanUtils.copyProperties(sku, skuInfo);
            skuInfo.setCostPrice(intToDecimal(sku.getCostPrice()));
            skuInfo.setSuggestPrice(intToDecimal(sku.getSuggestPrice()));
            skuInfo.setSalePrice(intToDecimal(sku.getSalePrice()));
            skuInfo.setThumbnail(sku.getImage());
            // 在 queryDetail 方法内
            SpecInfo specInfo = null;
            if (sku.getSpecs() != null && !sku.getSpecs().trim().isEmpty()) {
                try {
                    specInfo = JSON.parseObject(sku.getSpecs(), SpecInfo.class);
                } catch (Exception e) {
                    log.warn("解析商品规格信息失败，spuId: {}", id, e);
                    return R.fail("解析商品规格信息失败");
                }
            }
            skuInfo.setSpec(specInfo);
            skuInfoList.add(skuInfo);
        }
        spuInfo.setSkuInfoList(skuInfoList);
        spuInfo.setSkuIds(skuIds);
        return R.ok(spuInfo);
    }

    /**
     * 添加 SPUM 主信息
     */
    private Long addSpu(AddSpuReq req) {
        // 转换 categoryPath 为字符串路径
        String categoryPathStr = req.getCategoryPath() != null ?
                req.getCategoryPath().stream()
                        .map(String::valueOf)
                        .collect(Collectors.joining(Constants.CATEGORY_SEPARATOR)) :
                "";

        // 序列化 SkuSpace 为 JSON 字符串
        String skuSpacesJson = "{}";
        if (req.getSkuSpace() != null && !req.getSkuSpace().isEmpty()) {
            try {
                skuSpacesJson = JSON.toJSONString(req.getSkuSpace());
            } catch (Exception e) {
                log.error("SKU空间序列化失败", e);
                throw new BusinessException(-1, "SKU规格序列化失败");
            }
        }

        // 构建 SPUM 对象
        Spu spu = Spu.builder()
                .title(req.getTitle())
                .description(req.getDesc())
                .itemCode(req.getItemCode())
                .thumbnail(req.getThumbnail())
                .salePrice(yuanToCent(req.getSalePrice()))
                .suggestPrice(yuanToCent(req.getSuggestPrice()))
                .costPrice(yuanToCent(req.getCostPrice()))
                .stock(req.getStock() != null ? req.getStock() : 0)
                .skuSpaces(skuSpacesJson)
                .video(req.getVideo())
                .images(req.getImages() != null ? String.join(Constants.IMAGE_SEPARATOR, req.getImages()) : "")
                .categoryPath(categoryPathStr)
                .status(Constants.SPU_ON_SALE_STATUS)
                .saleType(req.getSaleType())
                .expressTemplateId(req.getExpressTemplateId())
                .expressFee(yuanToCent(req.getExpressFee()))
                .shopId(req.getShopId())
                .sort(req.getSort())
                .build();

        spuDao.insert(spu);
        return spu.getId();
    }

    /**
     * 添加 SKU 列表
     */
    private void addSku(AddSpuReq req, Long spuId, String spuTitle) {
        if (req.getSkuInfoList() == null || req.getSkuInfoList().isEmpty()) {
            return;
        }

        for (SkuInfo skuInfo : req.getSkuInfoList()) {
            // ✅ 使用 FastJSON 序列化 Spec
            String specJson = "{}";
            try {
                if (skuInfo.getSpec() != null) {
                    specJson = JSON.toJSONString(skuInfo.getSpec());
                }
            } catch (Exception e) {
                log.error("SKU规格序列化失败", e);
                throw new BusinessException(-1, "SKU规格数据异常");
            }

            // 构建 SKU 标题：SPU标题 + 规格值
            List<String> titleParts = new ArrayList<>();
            titleParts.add(spuTitle);
            if (skuInfo.getSpec() != null && skuInfo.getSpec().getValue() != null) {
                titleParts.addAll(skuInfo.getSpec().getValue());
            }
            String skuTitle = String.join(Constants.SKU_TITLE_SEPARATOR, titleParts);

            Sku sku = Sku.builder()
                    .spuId(spuId)
                    .title(skuTitle)
                    .status(Constants.SPU_ON_SALE_STATUS)
                    .image(skuInfo.getThumbnail())
                    .salePrice(yuanToCent(skuInfo.getSalePrice()))
                    .suggestPrice(yuanToCent(skuInfo.getSuggestPrice()))
                    .costPrice(yuanToCent(skuInfo.getCostPrice()))
                    .stock(skuInfo.getStock() != null ? skuInfo.getStock() : 0)
                    .specs(specJson)
                    .weight(skuInfo.getWeight())
                    .shopId(req.getShopId())
                    .build();

            // 单个插入
            int result = skuDao.insert(sku);
            if (result != 1) {
                log.error("插入SKU失败，影响行数：{}", result);
                throw new BusinessException(-1, "插入SKU失败");
            }
        }
    }

    /**
     * 添加 SPUM 与分类的关联关系
     */
    private void addOther(List<Long> categoryIds, Long spuId) {
        for (Long categoryId : categoryIds) {
            spuCategoryDao.insert(new SpuCategory(0, categoryId, spuId));
        }
    }

    /**
     * 金额转换：元 -> 分（存储为整数分）
     */
    private Long yuanToCent(BigDecimal yuan) {
        if (yuan == null) {
            return 0L;
        }
        return yuan.multiply(BigDecimal.valueOf(100)).longValue();
    }

    /**
     * 金额转换：分 -> 元（存储为整数分）
     */
    private BigDecimal intToDecimal(Long value) {
        if (value == null) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(value).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
    }

    /**
     * 校验商品数据：检查分类是否存在
     */
    private void checkSpuData(List<Long> categoryPath) {
        if (categoryPath == null || categoryPath.isEmpty()) {
            throw new BusinessException(-1, "分类路径不能为空");
        }

        List<Long> filtered = categoryPath.stream()
                .filter(id -> id != null && id > 0)
                .collect(Collectors.toList());

        if (filtered.size() != categoryPath.size()) {
            throw new BusinessException(-1, "存在无效的分类ID");
        }

        long totalCount = categoryDao.selectCount(
                new QueryWrapper<Category>()
                        .in("id", filtered));
        if (totalCount != filtered.size()) {
            log.error("查询分类失败，期望数量：{}，实际数量：{}", filtered.size(), totalCount);
            throw new BusinessException(-1, "部分分类不存在");
        }
    }
}

